"""
@author : linrh
@homepage : https://gitee.com/linrh-DUT
@version: 1.0.0
@when : 2023/5/24
@file: utils.py
"""
import re
import sys
from imp import reload
import uuid
import requests
import hashlib
import time
import json
import db_util

from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed

reload(sys)

db = db_util.get_db()
collection = db_util.get_collection(db, 'dict_en2zh')


def pdf2txt(path):
    """
    功能：解析pdf 文本，返回str
    path：pdf存放的文件夹路径
    """
    fp = open(path, 'rb')  # 以二进制读模式打开
    # 用文件对象来创建一个pdf文档分析器
    praser = PDFParser(fp)
    # 创建一个PDF文档
    doc = PDFDocument()
    # 连接分析器 与文档对象
    praser.set_document(doc)
    doc.set_parser(praser)

    # 提供初始化密码
    # 如果没有密码 就创建一个空的字符串
    doc.initialize()

    results = ''

    # 检测文档是否提供txt转换，不提供就忽略
    if not doc.is_extractable:
        raise PDFTextExtractionNotAllowed
    else:
        # 创建PDf 资源管理器 来管理共享资源
        rsrcmgr = PDFResourceManager()
        # 创建一个PDF设备对象
        laparams = LAParams()
        device = PDFPageAggregator(rsrcmgr, laparams=laparams)
        # 创建一个PDF解释器对象
        interpreter = PDFPageInterpreter(rsrcmgr, device)

        # 循环遍历列表，每次处理一个page的内容
        for page in doc.get_pages():  # doc.get_pages() 获取page列表
            interpreter.process_page(page)
            # 接受该页面的LTPage对象
            layout = device.get_result()
            # 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等 想要获取文本就获得对象的text属性，
            for x in layout:
                if (isinstance(x, LTTextBoxHorizontal)):
                    results += x.get_text()
    return results


def clear_txt(text):
    """
    功能：
    1. 处理换行合并
    2. 清理字符串中的空格、换行符、制表符

    str：字符串
    """
    # 处理换行合并
    text = merge_line(text)
    text = filter_symbol(text)
    return text


def merge_line(text):
    """
    功能：合并行
    text：文本
    """
    lines = []
    preflg = False
    preline = ''
    for line in text.split('\n'):
        # 前一行以'-'结尾，当前行合并
        if preflg is True:
            line = preline + line
            preflg = False
        if line.endswith('-'):
            preline = line[:-1]
            preflg = True
        else:
            lines.append(line)
    text = '\n'.join(lines)
    return text


def filter_symbol(text):
    """
    过滤特殊符号
    :param text:
    :return:
    """
    # 通过正则表达式过滤特殊符号
    text = re.sub(r'[^\w\s]', ' ', text)
    # 通过正则表达式过滤数字
    text = re.sub(r'\d+', ' ', text)
    # 通过正则表达式过滤单个字母
    text = re.sub(r'\b\w\b', '', text)
    # 通过正则表达式过滤空行
    text = re.sub(r'\n\s*\n', '\n', text)
    text = text.replace('\n', ' ')
    text = text.replace('ﬁ', 'fi')

    return text


def words_statistics(text):
    words = {}
    word_list = text.split(' ')
    for word in word_list:
        word = word.lower()
        if len(word) < 4:
            continue
        if word in words:
            words[word] += 1
        else:
            words[word] = 1
    words_num = sum([word[1] for word in words.items()])
    words = sorted(words.items(), key=lambda x: x[1], reverse=True)
    # map转list
    return list(map(lambda x: [x[0], x[1], round(x[1] * 100 / words_num, 2)], words))


# 有道翻译API
YD_URL = 'https://openapi.youdao.com/api'
YD_APP_KEY = '16ee2f5150c94e3b'
YD_APP_SECRET = 'sSaJQTg6av8lOCTOuahStybDNeq5MET2'


def yd_encrypt(signStr):
    hash_algorithm = hashlib.sha256()
    hash_algorithm.update(signStr.encode('utf-8'))
    return hash_algorithm.hexdigest()


def yd_truncate(q):
    if q is None:
        return None
    size = len(q)
    return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]


def yd_do_request(data):
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    return requests.post(YD_URL, data=data, headers=headers)


def yd_query(word):
    data = {}
    data['from'] = 'en'
    data['to'] = 'zh-CHS'
    data['signType'] = 'v3'
    curtime = str(int(time.time()))
    data['curtime'] = curtime
    salt = str(uuid.uuid1())
    signStr = YD_APP_KEY + yd_truncate(word) + salt + curtime + YD_APP_SECRET
    sign = yd_encrypt(signStr)
    data['appKey'] = YD_APP_KEY
    data['q'] = word
    data['salt'] = salt
    data['sign'] = sign
    data['domain'] = "computers"

    response = yd_do_request(data)
    content = json.loads(response.content.decode('utf-8'))
    if content['errorCode'] == "0":
        # 是否是单词
        isWord = content['isWord']
        if 'basic' in content:
            # 单词解释
            explains = content['basic']['explains']
        else:
            explains = []
        # 网络释义
        if 'web' in content:
            web = content['web']
        else:
            web = []
        # 翻译
        translation = content['translation']
        # 领域词汇
        isDomainSupport = content['isDomainSupport']
        # 插入数据库
        db_util.insert_one_duplicated(collection, {'word': word,
                                                   'translation': translation,
                                                   'web': web,
                                                   'explains': explains,
                                                   'isDomainSupport': isDomainSupport,
                                                   'isWord': isWord})

        return ' '.join(content['translation'])
    else:
        return ''
